Skip to content

Commit e77dff8

Browse files
committed
Initial code
1 parent 338ea8e commit e77dff8

39 files changed

+2831
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.env
2+
.mypy_cache
3+
.pyconlang
4+
.pytest_cache
5+
build
6+
*.egg-info

Makefile

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
.PHONY: all
2+
all: format lint type test
3+
4+
.PHONY: lint
5+
lint:
6+
isort . -q
7+
autoflake . --recursive \
8+
--exclude .env \
9+
--remove-unused-variables \
10+
--remove-all-unused-imports \
11+
--expand-star-imports \
12+
--in-place
13+
14+
.PHONY: format
15+
format:
16+
black .
17+
18+
.PHONY: type
19+
type:
20+
mypy --strict pyconlang
21+
22+
23+
.PHONY: test
24+
test:
25+
pytest -q
26+
27+
28+
.PHONY: env
29+
env:
30+
! [ -d .env ] && python3 -m venv .env || true
31+
32+
.PHONY: install
33+
install:
34+
yes | pip uninstall pyconlang
35+
pip install -e .[test]
36+
37+
diagrams.html: pyconlang/lexicon/parser.py
38+
python -m pyconlang.lexicon.parser
39+
40+
.PHONY: clean
41+
clean:
42+
rm -r .env
43+
rm diagrams.html

README.md

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
# Pyconlang
2+
A collection of Python utilities for conlanging.
3+
4+
### Installing
5+
Requires `python >= 3.10`:
6+
```shell
7+
$ pip install git+https://github.com/neta-elad/pyconlang.git
8+
```
9+
10+
No need to install Lexurgy separately,
11+
since it is bundled with Pyconlang.
12+
However, you do need Java 8 or higher installed
13+
(per Lexurgy's requirements).
14+
15+
## How to Use
16+
Initialize a new project:
17+
```shell
18+
$ pyconlang init -n Simatsan -a Biblaridion simatsan
19+
$ cd simatsan
20+
```
21+
22+
Run an interactive
23+
[Lexurgy](https://github.com/def-gthill/lexurgy)
24+
session:
25+
```shell
26+
$ pyconlang repl
27+
```
28+
29+
Compile the reference grammar and lexicon:
30+
```shell
31+
$ pyconlang book compile
32+
```
33+
or continuously watch for changes and re-compile:
34+
```shell
35+
$ pyconlang book watch
36+
```
37+
38+
For more information and help:
39+
```shell
40+
$ pyconlang --help
41+
```
42+
43+
## Book Format
44+
Pyconlang uses
45+
[Markdown](https://daringfireball.net/projects/markdown/),
46+
Lexurgy,
47+
and its own lexicon file-format
48+
to generate a reference grammar and lexicon
49+
for your conlang.
50+
The book's style is heavily inspired by
51+
David J. Peterson's template.
52+
53+
Under the hood, Pyconlang uses
54+
[Python-Markdown](https://python-markdown.github.io/)
55+
with several extensions to support
56+
[including files](https://github.com/neurobin/mdx_include)
57+
and [extended markup](https://python-markdown.github.io/extensions/).
58+
59+
Sound changes are defined in `changes.lsc`,
60+
and applied using Lexurgy.
61+
62+
Pyconlang's lexicon is defined in `lexicon.txt`.
63+
You define basic entries using the `entry` declaration:
64+
```
65+
entry <stone> *apak (n.) stone, pebble
66+
```
67+
68+
For some entries,
69+
you may want to define
70+
its form in some mid-point
71+
in the conlang's evolution.
72+
This is done using the `@rule` syntax:
73+
```
74+
entry <hard> *apaki@after-palatalization (adj.) hard, strong, stable
75+
```
76+
77+
When applying sound changes to this entry,
78+
only rules after (and including) `after-palatalization`
79+
will apply.
80+
You may find it useful to create explicit no-op rules
81+
in `changes.lsc`:
82+
```
83+
after-palatalization:
84+
unchanged
85+
```
86+
87+
Note that spaces are allowed
88+
when defining entries,
89+
so you need not restrict yourself to single words:
90+
```
91+
entry <to eat 27 strawberries> *mata (v.) to eat 27 strawberries, to be gluttonous
92+
```
93+
94+
You can also define affixes,
95+
to be used when inserting entries:
96+
```
97+
affix .PL *ikim
98+
affix COL. *ma
99+
100+
entry <gravel> <stone>.PL (n.) gravel, a pile of stones
101+
entry <monument> COL.<stone> (n.) monument, memorial site
102+
```
103+
Affixes can also be defined in some mid-point
104+
(using the `@rule` syntax)
105+
or by using compounds (`COL.<pile>`).
106+
107+
Additionally,
108+
you can define lexical sources of affixes,
109+
and a short description:
110+
```
111+
affix .PL *ikim (<big> <pile>) plural suffix for all nouns
112+
```
113+
When there is exactly one lexical source,
114+
you may omit the affix's form:
115+
```
116+
affix .PL (<pile>)
117+
```
118+
119+
Sometimes, a group of entries should be displayed
120+
with a list of forms.
121+
For example, all nouns show their collective and plural form.
122+
This is accomplished by templates:
123+
```
124+
template &noun $ $.PL COL.$
125+
126+
entry &noun <apple> *saka (n.) apple, any kind of tree-fruit
127+
```
128+
129+
You can see the diagrams for the lexicon syntax
130+
[here](https://htmlpreview.github.io/?https://github.com/neta-elad/pyconlang/blob/main/diagrams.html).
131+
132+
### Complete Example
133+
Given the sound changes `changes.lsc`:
134+
```
135+
Class vowel {a, e, i, o, u}
136+
137+
palatalization:
138+
k => ʃ / _ i
139+
140+
after-palatalization:
141+
unchanged
142+
143+
intervocalic-voicing:
144+
{p, t, k, s} => {b, d, g, z} / @vowel _ @vowel
145+
146+
romanizer:
147+
ʃ => sh
148+
```
149+
150+
and the lexicon `lexicon.txt`:
151+
```
152+
template &noun $ $.PL COL.$
153+
154+
affix .PL *ikim@after-palatalization (<big> <pile>) plural suffix for all nouns
155+
affix COL. (<pile>)
156+
157+
entry <big> *iki (adj.) big, great
158+
entry <pile> *ma (n.) pile, heap
159+
160+
entry &noun <stone> *apak (n.) stone, pebble
161+
entry <gravel> <stone>.PL (n.) gravel, a pile of stones
162+
entry <monument> COL.<stone> (n.) monument, memorial site
163+
```
164+
165+
The following entries will appear in the book:
166+
> ...
167+
> ## A
168+
> **abagigim** _\*apak_ + _\*ikim_ (n.) gravel, a pile of stones
169+
>
170+
> **abak**, **abagigim**, **maabak** _\*apak_ (n.) stone, pebble
171+
>
172+
> ...
173+
> ## I
174+
> **ishi** _\*iki_ (adj.) big, great
175+
>
176+
> ...
177+
> ## M
178+
> **ma** _\*ma_ (n.) pile, heap
179+
>
180+
> **maabak** _\*ma_ + _\*apak_ (n.) monument, memorial site
181+
>
182+
> ...
183+
184+
185+
186+
## TODO
187+
- [ ] `repl`: Interactive session with Lexurgy
188+
- [x] Enter proto form, get romanized modern form
189+
- [ ] Get phonetic modern form
190+
- [ ] Get simplified (no accents) romanized modern form
191+
- [ ] `lexurgy`: Evolving forms and auto-glomination
192+
- [x] Evolve and auto-glominate forms at the correct point of time
193+
- [ ] Handle stress
194+
- [ ] `lexicon`: Interactive lexicon
195+
- [ ] Define word by canonical
196+
- [ ] Find by canonical, proto, affix, or definition
197+
- [ ] `translator`: Automatic translation according to gloss
198+
- [ ] Evolve each form (with affixes)
199+
- [ ] Match-up forms and glosses
200+
- [ ] `book`: Generate a grammar/lexicon reference with less boilerplate
201+
- [x] Conlang-to-English lexicon, with entries, affixes and templates:
202+
- [ ] Affixes list
203+
- [ ] Phonology tables
204+
- [ ] Conjugation tables
205+
- [ ] Inline translation

0 commit comments

Comments
 (0)