A collection of Python utilities for conlanging.
Requires python >= 3.11:
$ pip install git+https://github.com/neta-elad/pyconlang.gitNo need to install Lexurgy separately, since it is bundled with Pyconlang. However, you do need Java 8 or higher installed (per Lexurgy's requirements).
Initialize a new project:
$ pyconlang init -n Simatsan -a Biblaridion simatsan
$ cd simatsanRun an interactive Lexurgy session:
$ pyconlang replCompile the reference grammar and lexicon:
$ pyconlang template compileor continuously watch for changes and re-compile:
$ pyconlang template watchFor more information and help:
$ pyconlang --helpPyconlang uses Markdown, Lexurgy, and its own lexicon file-format to generate a reference grammar and lexicon for your conlang. The book's style is heavily inspired by David J. Peterson's template.
Under the hood, Pyconlang uses Python-Markdown with several extensions to support including files and extended markup.
Sound changes are defined in changes.lsc,
and applied using Lexurgy.
Pyconlang's lexicon is defined in lexicon.pycl.
Each line defines one of three types of records:
entry, affix, and template.
No line breaks are allowed inside the definition of a single record.
You define basic entries using the entry declaration:
entry <stone> *apak (n.) stone, pebble
For some entries,
you may want to define
its form in some mid-point
in the conlang's evolution.
This is done using the @rule syntax:
entry <hard> *apaki@after-palatalization (adj.) hard, strong, stable
When applying sound changes to this entry,
only rules after (and including) after-palatalization
will apply.
You may find it useful to create explicit no-op rules
in changes.lsc:
after-palatalization:
unchanged
Note that spaces are allowed when defining entries, so you need not restrict yourself to single words:
entry <to eat 27 strawberries> *mata (v.) to eat 27 strawberries, to be gluttonous
You can also define affixes, to be used when inserting entries:
affix .PL *ikim
affix COL. *ma
entry <gravel> <stone>.PL (n.) gravel, a pile of stones
entry <monument> COL.<stone> (n.) monument, memorial site
Affixes can also be defined in some mid-point
(using the @rule syntax)
or by using compounds (COL.<pile>).
Additionally, you can define lexical sources of affixes, and a short description:
affix .PL *ikim (<big> <pile>) plural suffix for all nouns
When there is exactly one lexical source, you may omit the affix's form:
affix .PL (<pile>)
Sometimes, a group of entries should be displayed with a list of forms. For example, all nouns show their collective and plural form. This is accomplished by templates:
template &noun $ $.PL COL.$
entry &noun <apple> *saka (n.) apple, any kind of tree-fruit
You can see the diagrams for the lexicon syntax here.
Given the sound changes changes.lsc:
Class vowel {a, e, i, o, u}
palatalization:
k => ʃ / _ i
after-palatalization:
unchanged
intervocalic-voicing:
{p, t, k, s} => {b, d, g, z} / @vowel _ @vowel
romanizer:
ʃ => sh
and the lexicon lexicon.pycl:
template &noun $ $.PL COL.$
affix .PL *ikim@after-palatalization (<big> <pile>) plural suffix for all nouns
affix COL. (<pile>)
entry <big> *iki (adj.) big, great
entry <pile> *ma (n.) pile, heap
entry &noun <stone> *apak (n.) stone, pebble
entry <gravel> <stone>.PL (n.) gravel, a pile of stones
entry <monument> COL.<stone> (n.) monument, memorial site
The following entries will appear in the book:
...
abagigim [abagigim] *apak + *ikim (n.) gravel, a pile of stones
abak, abagigim, maabak [abak] *apak (n.) stone, pebble
...
ishi [iʃi] *iki (adj.) big, great
...
ma [ma] *ma (n.) pile, heap
maabak [maabak] *ma + *apak (n.) monument, memorial site
...
Inline translations (using the lexicon) can be inserted between two hash signs:
**An example: #*aki@after-palatalization <stone>.PL#.**will turn out as
An example: agi abagigim.
Block translations are available
using the !translate ... !translate syntax:
!translate
*aki@after-palatalization
<stone>.PL
!translatewill turn out as
agi abagigim
- Complete example project
- Custom error types?
- ? Combined, general repl
- Working with proto-forms
- Working with lexicon
- Defining words, affixes and templates in session
- Saving session
- Search for a word
- Var in lookup
$.PL
- Working with book
- Compile
- More powerful affixes:
- Branched affixes (depending on stem phonology / config)
- Frozen affixes (i.e. affixes defined in the modern language)
- Affixes with sound changes (e.g. voice initial consonant)
- Standalone affixes
- Not working for affixes with vars
- Correct order of affixes
-
repl: Interactive session with Lexurgy- Enter proto form, get romanized modern form
- Get phonetic modern form
- Get simplified (no accents) romanized modern form
- Traces
- History
- Auto-complete
- Error handling
- Partial trace, even when there's an error
- Take file as input
- Evolve up to a point
- Syntax highlighting
-
evolve: Evolving forms and auto-glomination- Evolve and auto-glominate forms at the correct point of time
- Handle stress
- Lexurgy error handling
- Traces
- Better cache
- Working with deromanizer and custom romanizers
- Evolve affixes with empty stem
- Evolve up to a point
-
lexicon: Interactive lexicon- Define word by lexeme
- Find by lexeme, proto, affix, or definition
- Protos to take affixes as well
- Batch evolve, using dependency graph?
- Better cache
- On-the-fly affixes? Syntax for compounding two words without an explicit affix
- Affixes with empty stem
- Vars/forms with rules
$.PL@proto
-
translator: Automatic translation according to gloss- Evolve each form (with affixes)
- Match-up forms and glosses
- Better cache
- Full-text search over everything (proto, modern, phonetic, definitions, etc.) whoosh
- Affixes with empty stem
-
book: Generate a grammar/lexicon reference with less boilerplate- Conlang-to-English lexicon, with entries, affixes and templates:
- Only rebuild lexicon when changed
- Affixes list
- Phonology tables
- Conjugation tables
- Inline translation
- Robust against errors
- Block translation
- Options for block/inline translation
- Show before/after
- Phonetic/modern/gloss